Skip to content

provide event for redis state expiry#6194

Merged
adhami3310 merged 3 commits intomainfrom
provide-event-for-redis-state-expiry
Mar 19, 2026
Merged

provide event for redis state expiry#6194
adhami3310 merged 3 commits intomainfrom
provide-event-for-redis-state-expiry

Conversation

@adhami3310
Copy link
Copy Markdown
Member

No description provided.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 19, 2026

Merging this PR will not alter performance

✅ 8 untouched benchmarks


Comparing provide-event-for-redis-state-expiry (32a343d) with main (d45a1bb)

Open in CodSpeed

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 19, 2026

Greptile Summary

This PR propagates the triggering Event object through the Redis state-manager lock stack so that lock expiry errors and debug messages can surface which event was executing when the lock expired.

Key changes:

  • StateModificationContext now allows event: Event | None (was Event) so proxies with no current event can pass None explicitly
  • _lock in StateManagerRedis embeds the event name in the Redis lock ID (format {event_name}_{uuid_hex}), making it easier to identify the owning event when inspecting Redis
  • LockExpiredError messages now include both the current lock ID (stored in Redis) and the expected lock ID, giving much richer diagnostics
  • StateProxy stores and forwards the Event reference through all modify_state calls, including child proxies created via get_state
  • The upload event handler and _process_background now pass the event into modify_state_with_links / StateProxy

Confidence Score: 4/5

  • Safe to merge with minor stylistic fixes — no logic regressions; changes are additive and only affect observability/debugging of Redis lock expiry.
  • The core logic of lock acquisition and release is unchanged; the PR only threads event context through existing call chains. The two items lowering the score are: (1) the _ separator in the lock ID format risks ambiguity when parsing lock IDs that contain event names with underscores, and (2) the new **context parameter in the public modify_state method is undocumented.
  • reflex/istate/manager/redis.py — review the lock ID separator choice; reflex/app.py — missing docstring for **context

Important Files Changed

Filename Overview
reflex/istate/manager/redis.py Passes event_name into _lock to embed event context in Redis lock IDs; improves LockExpiredError messages with current/expected lock ID values. Minor ambiguity in lock ID format when event names contain underscores.
reflex/istate/manager/init.py Widens StateModificationContext.event type from ReadOnly[Event] to `ReadOnly[Event
reflex/istate/proxy.py Threads the event parameter through StateProxy.__init__, __aenter__, and get_state so background tasks carry event context into subsequent modify_state calls. Clean propagation logic.
reflex/app.py Adds **context: Unpack[StateModificationContext] to modify_state and propagates it to the state manager; passes event to StateProxy in _process_background and to modify_state_with_links in the upload handler. Missing docstring for the new parameter.
reflex/state.py Single-line change passing event to StateProxy constructor inside _process; consistent with equivalent change in app.py.

Sequence Diagram

sequenceDiagram
    participant Client
    participant App
    participant StateProxy
    participant StateManagerRedis
    participant Redis

    Client->>App: Event (e.g. on_click)
    App->>App: _process_background(state, event)
    App->>StateProxy: StateProxy(substate, event)
    Note over StateProxy: stores _self_event = event

    StateProxy->>App: modify_state(token, background=True, event=self._self_event)
    App->>StateManagerRedis: modify_state_with_links(token, event=event)
    StateManagerRedis->>StateManagerRedis: _try_modify_state(token, event=event)
    Note over StateManagerRedis: event_name = event.name
    StateManagerRedis->>StateManagerRedis: _lock(token, event_name=event_name)
    Note over StateManagerRedis: lock_id = f"{event_name}_{uuid_hex}".encode()
    StateManagerRedis->>Redis: SET lock_key lock_id PX lock_expiration
    Redis-->>StateManagerRedis: OK

    StateManagerRedis-->>App: yields state
    App-->>StateProxy: yields mutable_state

    StateProxy->>StateManagerRedis: set_state(token, state, lock_id=lock_id, event=event)
    StateManagerRedis->>Redis: GET lock_key
    Redis-->>StateManagerRedis: existing_lock_id
    alt lock_id matches
        StateManagerRedis->>Redis: SET substate_key pickle_state
    else lock expired
        StateManagerRedis->>StateManagerRedis: LockExpiredError\n"Current lock id: {existing_lock_id!r},\nexpected: {lock_id!r}.\nHappened in event: {event.name}"
    end
Loading

Comments Outside Diff (1)

  1. reflex/app.py, line 1585-1596 (link)

    P2 Missing docstring for **context parameter

    The **context: Unpack[StateModificationContext] parameter was added to modify_state but is not documented in the docstring. Since this is a public API method, callers (including the upload handler and StateProxy) need to know what can be passed.

Last reviewed commit: "provide event for re..."

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@adhami3310 adhami3310 merged commit 0a5e76e into main Mar 19, 2026
47 checks passed
@adhami3310 adhami3310 deleted the provide-event-for-redis-state-expiry branch March 19, 2026 19:20
adhami3310 added a commit that referenced this pull request Mar 19, 2026
* provide event for redis state expiry

* sad

* use : instead of _

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants